﻿/* 
This file is part of Ingo Karstein's Long Path Support project

**Do not remove this comment**

Please see the project homepage at CodePlex:
  http://longpathsupport.codeplex.com/

Please see my blog:
  http://ikarstein.wordpress.com

This code is used in the project "RoboPowerCopy"
  http://robopowercopy.codeplex.com

Licence: GPLv2
    Ingo Karstein's SharePoint 2010 Custom Ribbon Demo
    Copyright (C) 2011  Ingo Karstein, ikarstein@hotmail.com

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security;

public class LongFileInfo
{
    private string _name;
    private string _fullname;
    private int _prefixLen = 0;
    private DateTime _lastWriteTime;
    private DateTime _lastWriteTimeUtc;
    private DateTime _lastAccessTime;
    private DateTime _lastAccessTimeUtc;
    private DateTime _creationTime;
    private DateTime _creationTimeUtc;
    private System.IO.FileAttributes _attributes;


    [SecuritySafeCritical]
    public LongFileInfo(string fileName)
    {
        _fullname = LongPathSupport.GetFullName(fileName);

        if( !_fullname.StartsWith(@"\\?\") )
        {
            if( _fullname.StartsWith(@"\\") )
            {
                _fullname = @"\\?\UNC\" + _fullname.Substring(2);
                _prefixLen = 8;
            }
            else
            {
                _fullname = @"\\?\" + _fullname;
                _prefixLen = 4;
            }
        }
        else
        {
            if( _fullname.StartsWith(@"\\?\UNC\") )
                _prefixLen = 8;
            else
                _prefixLen = 4;
        }

        if( string.IsNullOrEmpty(_fullname) )
            throw new Exception("Path invalid");

        _name = System.IO.Path.GetFileName(_fullname);
        Refresh();
    }

    [SecuritySafeCritical]
    public System.IO.FileStream Open(System.IO.FileMode mode)
    {
        return this.Open(mode, System.IO.FileAccess.ReadWrite, System.IO.FileShare.None);
    }

    [SecuritySafeCritical]
    public System.IO.FileStream Open(System.IO.FileMode mode, System.IO.FileAccess access)
    {
        return this.Open(mode, access, System.IO.FileShare.None);
    }

    [SecuritySafeCritical]
    public System.IO.FileStream Open(System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share)
    {
        return LongPathSupport.Open(_fullname, access, mode, share);
    }

    [SecuritySafeCritical]
    public System.IO.FileStream OpenRead()
    {
        return LongPathSupport.Open(_fullname, System.IO.FileAccess.Read, System.IO.FileMode.Open, System.IO.FileShare.Read);
    }

    [SecuritySafeCritical]
    public System.IO.StreamReader OpenText()
    {
        return new System.IO.StreamReader(LongPathSupport.Open(_fullname, System.IO.FileAccess.ReadWrite, System.IO.FileMode.Open, System.IO.FileShare.None));
    }

    [SecuritySafeCritical]
    public System.IO.FileStream OpenWrite()
    {
        return LongPathSupport.Open(_fullname, System.IO.FileAccess.Write, System.IO.FileMode.OpenOrCreate, System.IO.FileShare.None);
    }


    [SecuritySafeCritical]
    public System.IO.FileStream Create()
    {
        return LongPathSupport.Open(_fullname, System.IO.FileAccess.Write, System.IO.FileMode.CreateNew, System.IO.FileShare.None);
    }

    [SecuritySafeCritical]
    public System.IO.StreamWriter CreateText()
    {
        return new System.IO.StreamWriter(LongPathSupport.Open(_fullname, System.IO.FileAccess.Write, System.IO.FileMode.CreateNew, System.IO.FileShare.None));
    }


    public override string ToString()
    {
        return _fullname;
    }

    public void Delete()
    {
        LongPathSupport.DeleteFile(_fullname);
    }

    public LongDirectoryInfo Directory
    {
        [SecuritySafeCritical]
        get
        {
            string directoryName = this.DirectoryName;
            if( directoryName == null )
            {
                return null;
            }
            return new LongDirectoryInfo(directoryName);
        }
    }

    public string DirectoryName
    {
        [SecuritySafeCritical]
        get
        {
            string directoryName = LongPathSupport.GetDirectoryName(_fullname);
            if( directoryName != null )
            {
                //LongPathSupport.GetFileIOPermission(FileIOPermissionAccess.PathDiscovery, directoryName).Demand();
            }
            return directoryName;
        }
    }

    public bool Exists
    {
        [SecuritySafeCritical]
        get
        {
            return LongPathSupport.FileExists(_fullname);
        }
    }

    public string Name
    {
        get
        {
            return this._name;
        }
    }

    public string FullName
    {
        get
        {
            return _fullname.Substring(_prefixLen);
        }
    }

    public string FullQualifiedName
    {
        get
        {
            return _fullname;
        }
    }

    public long Length
    {
        [SecuritySafeCritical]
        get
        {
            return LongPathSupport.FileLength(_fullname);
        }
    }

    public void Refresh()
    {
        if( !Exists )
        {
            DateTime minUtc = new DateTime(1601, 01, 01, 00, 00, 00, 00, DateTimeKind.Utc);
            DateTime minLocal = minUtc.ToLocalTime();
            _creationTime = _lastAccessTime = _lastWriteTime = minLocal;
            _creationTimeUtc = _lastAccessTimeUtc = _lastWriteTimeUtc = minUtc;
            _attributes = (System.IO.FileAttributes)( -1 );
        }
        else
        {
            if( !FileTimeHelper.GetFileTimes(_fullname, out _creationTime, out _lastAccessTime, out _lastWriteTime) )
                throw new System.IO.IOException("Could not get file times");
            if( !FileTimeHelper.GetFileTimesUtc(_fullname, out _creationTimeUtc, out _lastAccessTimeUtc, out _lastWriteTimeUtc) )
                throw new System.IO.IOException("Could not get file times");
            System.IO.FileAttributes? _tmp = (System.IO.FileAttributes)AttributeHelper.GetAttributes(_fullname);
            if( _tmp == null )
                throw new System.IO.IOException("Could not get file attributes");
            _attributes = (System.IO.FileAttributes)_tmp;
        }
    }



    public static bool TypeAvailable()
    {
        return true;
    }

    public DateTime LastWriteTime
    {
        get
        {
            return _lastWriteTime;
        }
        set
        {
            _lastWriteTime = value;
            if( !FileTimeHelper.SetFileTimes(_fullname, null, null, _lastWriteTime) )
                throw new System.IO.IOException("Could not set LastWriteTime");
        }
    }
    public DateTime LastWriteTimeUtc
    {
        get
        {
            return _lastWriteTimeUtc;
        }
        set
        {
            _lastWriteTimeUtc = value;
            if( !FileTimeHelper.SetFileTimesUtc(_fullname, null, null, _lastWriteTimeUtc) )
                throw new System.IO.IOException("Could not set LastWriteTimeUtc");
        }
    }
    public DateTime LastAccessTime
    {
        get
        {
            return _lastAccessTime;
        }
        set
        {
            _lastAccessTime = value;
            if( !FileTimeHelper.SetFileTimes(_fullname, null, _lastAccessTime, null) )
                throw new System.IO.IOException("Could not set LastAccessTime");
        }
    }
    public DateTime LastAccessTimeUtc
    {
        get
        {
            return _lastAccessTimeUtc;
        }
        set
        {
            _lastAccessTimeUtc = value;
            if( !FileTimeHelper.SetFileTimesUtc(_fullname, null, _lastAccessTimeUtc, null) )
                throw new System.IO.IOException("Could not set LastAccessTimeUtc");
        }
    }
    public DateTime CreationTime
    {
        get
        {
            return _creationTime;
        }
        set
        {
            _creationTime = value;
            if( !FileTimeHelper.SetFileTimes(_fullname, _creationTime, null, null) )
                throw new System.IO.IOException("Could not set CreationTime");
        }
    }
    public DateTime CreationTimeUtc
    {
        get
        {
            return _creationTimeUtc;
        }
        set
        {
            _creationTimeUtc = value;
            if( !FileTimeHelper.SetFileTimesUtc(_fullname, _creationTimeUtc, null, null) )
                throw new System.IO.IOException("Could not set CreationTimeUtc");
        }
    }
    public System.IO.FileAttributes Attributes
    {
        get
        {
            return _attributes;
        }
        set
        {
            _attributes = value;
            if( !AttributeHelper.SetAttributes(_fullname, _attributes) )
                throw new System.IO.IOException("Could not set file attributes");
        }
    }


}

